﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace DllMethodCalledAnalysis45.Models
{
    public class ProjectConfig
    {
        public string FileName { get; set; }

        public string ProjectPath { get; set; }

        public string[] StartMethods { get; set; }

        public string[] SearchPaths { get; set; }

        public string[] CheckNames { get; set; }

        public MethodFilter MethodFilter { get; set; }

        public AssemblyFilter AssemblyFilter { get; set; }
    }

    public class AssemblyFilter
    {
        public string NameStartWith { get; set; }

        public string NameContain { get; set; }

        public List<AssemblyFilter> Musts { get; set; }

        public List<AssemblyFilter> Shoulds { get; set; }

        public AssemblyFilter Not { get; set; }

        public bool IsPassFilter(Assembly assembly)
        {
            if (assembly == null)
                return false;

            // 程序集名称以xxx开头
            if (string.IsNullOrEmpty(NameStartWith) != true)
                return assembly.FullName.StartsWith(NameStartWith);

            // 程序集名称包含xxx
            if (string.IsNullOrEmpty(NameContain) != true)
                return assembly.FullName.Contains(NameContain);

            // 必须项，必须全都通过
            if (Musts?.Any() == true)
                return Musts.All(n => n.IsPassFilter(assembly));

            // 可选项，必须通过一个
            if (Shoulds?.Any() == true)
                return Shoulds.Any(n => n.IsPassFilter(assembly));

            // 取反结论必然为反
            if (Not != null)
                return Not.IsPassFilter(assembly) != true;

            return false;
        }
    }

    public class MethodFilter
    {
        public AssemblyFilter AssemblyFilter { get; set; }

        public string FullNameStartWith { get; set; }

        public string FullNameContain { get; set; }

        public string NameStartWith { get; set; }

        public string NameContain { get; set; }

        public List<MethodFilter> Musts { get; set; }

        public List<MethodFilter> Shoulds { get; set; }

        public MethodFilter Not { get; set; }

        public bool IsPassFilter(MethodInfo method)
        {
            if (method == null)
                return false;

            // 程序集过滤器
            if (AssemblyFilter != null)
                return AssemblyFilter.IsPassFilter(method.DeclaringType.Assembly);

            // 名称以xxx开头
            if (string.IsNullOrEmpty(FullNameStartWith) != true)
                return method.Name.StartsWith(FullNameStartWith);

            // 名称包含xxx
            if (string.IsNullOrEmpty(FullNameContain) != true)
                return method.Name.Contains(FullNameContain);

            // 名称以xxx开头
            if (string.IsNullOrEmpty(NameStartWith) != true)
                return method.Name.StartsWith(NameStartWith);

            // 名称包含xxx
            if (string.IsNullOrEmpty(NameContain) != true)
                return method.Name.Contains(NameContain);

            // 必须项，必须全都通过
            if (Musts?.Any() == true)
                return Musts.All(n => n.IsPassFilter(method));

            // 可选项，必须通过一个
            if (Shoulds?.Any() == true)
                return Shoulds.Any(n => n.IsPassFilter(method));

            // 取反结论必然为反
            if (Not != null)
                return Not.IsPassFilter(method) != true;

            return false;
        }
    }
}
